import { ref, reactive, toRefs, unref, toValue } from 'vue'
import { useSystemStore } from '@/stores/system'
import { isObject } from 'lodash-es'

export const useGetData = (api, params = {}, options = {}) => {
    const { defaultValue = [] } = options
    const data = ref(defaultValue)
    api(params)
        .then(result => {
            data.value = result || defaultValue
        }).catch(error => {
            window.defaultCatchError(error)
            data.value = defaultValue
        })
    return {
        data
    }
}

/**
 * 使用请求
 * @param {Function} api api函数
 * @param {Record<string, unknown>} params 参数
 * @param {{ defaultValue?: unknown }} options 配置 defaultValue: 定义默认值
 */
export const useRequest = (api, params = {}, options = {}) => {
    const { defaultValue = [] } = options
    let data = defaultValue
    return new Promise(async (resolve, reject) => {
        try {
            const result = await api(params) || defaultValue
            resolve(result)
        } catch (error) {
            window.defaultCatchError(error)
            resolve(data)
        }
    })
}

/**
 * 字典
 * @param {{ sysName: string, typeName: string }} params
 * @param {{ numberValue?: boolean }} opts
 */
export const useDict = (params, opts = {}) => {
    const { numberValue = false } = opts
    if (!isObject(params)) {
        console.warn('useDict params 必传对象')
        return
    }

    const systemStore = useSystemStore()

    const state = reactive({
        list: [],
        map: {}
    })

    return toRefs(state)
}

/**
 * 自定义字典
 * @param {{
 * api: () => Promise<unknown>,
 * labelField?: string,
 * valueField?: string,
 * params?: Record<string, unknown>,
 * customFn?: () => void,
 * immediate?: boolean
 * }} opts
 */
export const useCustomDict = (opts = {}) => {
    const { api: apiFunction = async () => {}, params = {}, labelField = 'label', valueField = 'value', customFn = null, immediate = true } = opts

    const state = reactive({
        list: [],
        map: {}
    })

    const refresh = () => {
        return apiFunction(toValue(params))
            .then((result = []) => {
                if (typeof customFn === 'function') {
                    customFn({ result, state })
                    return
                }
    
                const map = {}
    
                const list = result.map(item => {
                    const label = item[labelField]
                    const value = item[valueField]
                    const result = {
                        ...item,
                        label,
                        value
                    }
                    map[value] = result
                    return result
                })
    
                Object.assign(state, {
                    map,
                    list
                })
            }).catch(error => {
                window.defaultCatchError(error)
                Object.assign(state, {
                    map: {},
                    list: []
                })
            })
    }

    const reset = () => {
        Object.assign(state, {
            list: [],
            map: {}
        })
    }

    if (immediate) refresh()

    return {
        ...toRefs(state),
        refresh,
        reset
    }
}

export const getColValByMap = (row, item, map, labelName = 'dictName') => {
    return unref(map)[row[item.prop]]?.[labelName] || ''
}